const type = (param: any) => Object.prototype.toString.call(param).slice(8, -1);

// 1.邮箱验证
export const isEmail = (s: string) => /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/.test(s);
// 2.手机号码验证
export const isMobile = (s: string) => /^1[0-9]{10}$/.test(s);
// 3.电话号码验证
export const isPhone = (s: string) => /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s);
// 4.是否url地址
export const isURL = (s: string) => /^http[s]?:\/\/.*/.test(s);
// 5.是否字符串
export const isString = (o: any) => type(o) === 'String';
// 6.是否数字
export const isNumber = (o: any) => type(o) === 'Number';
// 7.是否boolean
export const isBoolean = (o: any) => type(o) === 'Boolean';
// 8.是否函数
export const isFunction = (o: any) => type(o) === 'Function';
// 9.是否为null
export const isNull = (o: any) => type(o) === 'Null';
// 10.是否undefined
export const isUndefined = (o: any) => type(o) === 'Undefined';
// 11.是否对象
export const isObj = (o: any) => type(o) === 'Object';
// 12.是否数组
export const isArray = (o: any) => type(o) === 'Array';
// 13.是否时间
export const isDate = (o: any) => type(o) === 'Date';
// 14.是否正则
export const isRegExp = (o: any) => type(o) === 'RegExp';
// 15.是否错误对象
export const isError = (o: any) => type(o) === 'Error';
// 16.是否Symbol函数
export const isSymbol = (o: any) => type(o) === 'Symbol';
// 17.是否Promise对象
export const isPromise = (o: any) => type(o) === 'Promise';
// 18.是否Set对象
export const isSet = (o: any) => type(o) === 'Set';

/**
 * @description 判断url是否是http或https
 * @param {string} path
 * @returns {Boolean}
 */
export function isHttp(path: string) {
  return path.indexOf('http://') !== -1 || path.indexOf('https://') !== -1;
}

/**
 * @description 判断path是否为外链
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path: string) {
  return /^(https?:|mailto:|tel:)/.test(path);
}

// 24.是否为PC端
export const isPC = () => {
  const userAgentInfo = navigator.userAgent;
  const Agents = [
    'Android',
    'iPhone',
    'SymbianOS',
    'Windows Phone',
    'iPad',
    'iPod',
  ];
  let flag = true;
  // eslint-disable-next-line no-plusplus
  for (let v = 0; v < Agents.length; v++) {
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
      flag = false;
      break;
    }
  }
  return flag;
};
// 25.判断类型集合
export const checkStr = (
  str: string,
  // eslint-disable-next-line no-shadow
  checkType:
    | 'phone'
    | 'tel'
    | 'card'
    | 'pwd'
    | 'postal'
    | 'QQ'
    | 'email'
    | 'money'
    | 'URL'
    | 'IP'
    | 'date'
    | 'number'
    | 'english'
    | 'chinese'
    | 'lower'
    | 'upper'
    | 'HTML',
) => {
  switch (checkType) {
    case 'phone': // 手机号码
      return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str);
    case 'tel': // 座机
      return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str);
    case 'card': // 身份证
      return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
    case 'pwd': // 密码以字母开头，长度在6~18之间，只能包含字母、数字和下划线
      return /^[a-zA-Z]\w{5,17}$/.test(str);
    case 'postal': // 邮政编码
      return /[1-9]\d{5}(?!\d)/.test(str);
    case 'QQ': // QQ号
      return /^[1-9][0-9]{4,9}$/.test(str);
    case 'email': // 邮箱
      return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(str);
    case 'money': // 金额(小数点2位)
      return /^\d*(?:\.\d{0,2})?$/.test(str);
    case 'URL': // 网址
      return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/.test(
        str,
      );
    case 'IP': // IP
      return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(
        str,
      );
    case 'date': // 日期时间
      return (
        /^(\d{4})-(\d{2})-(\d{2}) (\d{2})(?::\d{2}|:(\d{2}):(\d{2}))$/.test(
          str,
        ) || /^(\d{4})-(\d{2})-(\d{2})$/.test(str)
      );
    case 'number': // 数字
      return /^[0-9]$/.test(str);
    case 'english': // 英文
      return /^[a-zA-Z]+$/.test(str);
    case 'chinese': // 中文
      return /^[\\u4E00-\\u9FA5]+$/.test(str);
    case 'lower': // 小写
      return /^[a-z]+$/.test(str);
    case 'upper': // 大写
      return /^[A-Z]+$/.test(str);
    case 'HTML': // HTML标记
      return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str);
    default:
      return true;
  }
};
// 26.严格的身份证校验
export const isCardID = (sId: string) => {
  if (!/(^\d{15}$)|(^\d{17}(\d|X|x)$)/.test(sId)) {
    return false;
  }
  // 身份证城市
  const aCity = {
    11: '北京',
    12: '天津',
    13: '河北',
    14: '山西',
    15: '内蒙古',
    21: '辽宁',
    22: '吉林',
    23: '黑龙江',
    31: '上海',
    32: '江苏',
    33: '浙江',
    34: '安徽',
    35: '福建',
    36: '江西',
    37: '山东',
    41: '河南',
    42: '湖北',
    43: '湖南',
    44: '广东',
    45: '广西',
    46: '海南',
    50: '重庆',
    51: '四川',
    52: '贵州',
    53: '云南',
    54: '西藏',
    61: '陕西',
    62: '甘肃',
    63: '青海',
    64: '宁夏',
    65: '新疆',
    71: '台湾',
    81: '香港',
    82: '澳门',
    91: '国外',
  };
  if (!aCity[parseInt(sId.substr(0, 2), 10)]) {
    return false;
  }

  // 出生日期验证
  const sBirthday = `${sId.substr(6, 4)}-${Number(sId.substr(10, 2))}-${Number(
    sId.substr(12, 2),
  )}`.replace(/-/g, '/');
  const d = new Date(sBirthday);
  if (sBirthday !== `${d.getFullYear()}/${d.getMonth() + 1}/${d.getDate()}`) {
    return false;
  }

  // 身份证号码校验
  let sum = 0;
  const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  const codes = '10X98765432';
  // eslint-disable-next-line no-plusplus
  for (let i = 0; i < sId.length - 1; i++) {
    sum += Number(sId[i]) * weights[i];
  }
  const last = codes[sum % 11]; // 计算出来的最后一位身份证号码
  if (sId[sId.length - 1] !== last) {
    return false;
  }

  return true;
};
